/**
 * $Id$
 *
 * Developed 2004 Sun Microsystems, Inc.
 *
 * Use is subject to licence terms.
 *
 * This software uses software developed by the Apache Software Foundation
 * Copyright (c) 1999-2004 The Apache Software Foundation.
 *
 *
 * HandlerFactory for our own url handlers
 *
 * Created on 24. März 2005, 22:18
 */

package com.google.cse.emea.jct.utils.protocols;

import java.io.PrintStream;
import java.net.*;
import java.util.HashMap;

/**
 * Class to register the self written url protocols to the system. 
 * Used from TransferTool and
 * BrickAntTask as well as the tests.
 *
 * @author Jens.Trapp@Sun.com
 * @version $Revision$
 */
public class HandlerFactory
    implements URLStreamHandlerFactory
{
    private static boolean registered = false;
    private static HashMap handlers = new HashMap();
    private static HandlerFactory instance;
    
    /**
     * Should not be instanciated by users.
     */
    private HandlerFactory()
    {
        //Singleton
    }
    
    /**
     * Returns the Singleton Object and creates it if nessesary.
     */
    public static synchronized HandlerFactory getInstance()
    {
        if (instance == null)
        {
            instance = new HandlerFactory();
        }
        return instance;
    }
    
    /**
     * Register Protocoll. Registering the the Stream Handler Factory can only happen once in the
     * application lifetime. This method assures, that no error will occur, if the method is called
     * twice. But if any other class is calling registering it's protocols, the program will throw
     * an exception.
     */
    public static void registerProtocol()
    {
        if (!registered)
        {
            
            try
            {
                URL.setURLStreamHandlerFactory(getInstance());
            }
            catch(Error error)
            {
                System.err.println("Error while initializing cpath handler: "+error);
                //Now try, if the cpath may be used anyway:

                try
                {
                    URL config = new URL("cpath:///config/config.xml");
                }
                catch(MalformedURLException malfaromedException)
                {
                    System.err.println("Can't use cpath handler: "+malfaromedException); 
                    throw error;
                }
                
                
            }
        }
        registered = true;
    }

    /**
     * Resolve handler from protocol name. Currently cpath and sanmp supported.
     * @param protocol protocol name as used in url
     * @return Handler class
     */
    public URLStreamHandler createURLStreamHandler(String protocol) 
    {
       // System.out.println(this.getClass().getName()+ ": creating url stram handler for "+protocol);
        URLStreamHandler handler = (URLStreamHandler) handlers.get(protocol);
        if (protocol==null)
            throw new RuntimeException("No protocl specified");
        if (handler == null)
        {
            try 
            {
//                if (protocol.equals(ProtocolPrefixEnum.SAMP))
//                {
//                    handler = (URLStreamHandler) Class.forName("custromHandler").newInstance();
//                    handlers.put(protocol, handler);
//                }
                if (protocol.equals(ProtocolPrefixEnum.CPATH))
                {
                    handler =  (URLStreamHandler) Class.forName("com.google.cse.emea.jct.utils.protocols.cpath.Handler").newInstance();
                    handlers.put(protocol, handler);
                }
            } 
            catch (ClassNotFoundException e) 
            {
                throw new RuntimeException(e);
            } 
            catch (InstantiationException e) 
            {                
                throw new RuntimeException(e);
            }
            catch (IllegalAccessException e) 
            {
                throw new RuntimeException(e);
            }
        }

            
        return handler;
    }

    /** Small helper to load arbitrary files through an url */
    /**
    public static void main(String[] args)
    {
        int i = 0;

        if (args.length == 0)
        {
            System.out.println("please specify url (e.g sanmp://user:passwd@volumename/path/to/file");

        }
        else if (args[0].startsWith("-v"))
        {
            printProperty(System.out, "java.class.path");
            printProperty(System.out, "java.protocol.handler.pkgs");

            i++;
        }
        while (i < args.length)
        {
            try
            {
                URL url = new URL(args[i++]);
                InputStream stream = url.openStream();
                byte[] file = de.sun.commons.io.FileUtils.readAll(stream);
                stream.close();
                System.out.println(new String(file));
            }
            catch (Exception exception)
            {
                exception.printStackTrace();
            }
        }
    }*/

    /**
     * Print out a system property
     */
    private static void printProperty(PrintStream out, String property)
    {
        out.println(property + " = " + System.getProperty(property));
    }
}